// System headers
#include "hw_memmap.h"
#include "hw_types.h"
#include "adc.h"
#include "debug.h"
#include "gpio.h"
#include "interrupt.h"
#include "sysctl.h"
#include "timer.h"
#include "uart.h"
#include "osram96x16x1.h"
#include "hw_ints.h"
			   
#include "interr.h"
#include "coefficients.h"
#include "equation.h"

#define PUSH_BUTTON GPIO_PIN_4

// Global variables
unsigned char state = 0;
char flag = 0;
unsigned int seconds = 0;
char coeffA[10] = {'\0'};
char coeffB[10] = {'\0'};
char coeffC[10] = {'\0'};
char equation[30];

// Function prototypes
int GetDataFromACP(void);
int screenStart(void);

// Draws the main menu on the display
void menuDraw(void)
{
	OSRAM96x16x1StringDraw("EnterA", 6*1, 0);
	OSRAM96x16x1StringDraw("EnterB", 6*10, 0);
	OSRAM96x16x1StringDraw("EnterC", 6*1, 1);	
}
//
// Returns an integer between 0 and 100 from the ADC
// Returns the previous result if the value of the new one is within 5% range 
//
int GetDataFromACP()
{
	unsigned long value[8];
	static int per;
	static int perTemp=0;
	
	ADCProcessorTrigger(ADC_BASE, 0);
	while(!ADCIntStatus(ADC_BASE, 0, false));
	ADCSequenceDataGet(ADC_BASE, 0, value);		
	
	if(perTemp<(value[0]-51) || perTemp>(value[0]+51)) 
	{
		perTemp=value[0];
		per = (int)((value[0]*100)/1023);
	}	
	/;
}
//
// If 30 seconds have passed since last action, starts the screen saver sequence
//
int screenStart(void)
{
	if(seconds== 30)
	{
		TimerDisable(TIMER2_BASE, TIMER_A);	
		OSRAM96x16x1Clear();
		buildEquation(coeffA, coeffB, coeffC);
		moveEquation(equation);
    	TimerEnable(TIMER2_BASE, TIMER_A);	
	    menuDraw();
		return 1;
	}
	return 0;
}

int main(void)
{
	int result;
	int resultTemp;
	
	//
	// Set the clocking to run at 20MHz from the PLL.
	//
	SysCtlClockSet(SYSCTL_SYSDIV_10 | SYSCTL_USE_PLL | SYSCTL_OSC_MAIN |
	SYSCTL_XTAL_6MHZ);
	
	//
	// Enable the peripherals used by the application.
	//
	SysCtlPeripheralEnable(SYSCTL_PERIPH_ADC);
	SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOC);
	SysCtlPeripheralEnable(SYSCTL_PERIPH_TIMER1);
    SysCtlPeripheralEnable(SYSCTL_PERIPH_TIMER0);
	SysCtlPeripheralEnable(SYSCTL_PERIPH_TIMER2);
	
	//
	// Configure the ADC to sample the potentiometer when the timer expires.
	//
	ADCSequenceConfigure(ADC_BASE, 0, ADC_TRIGGER_PROCESSOR, 0);
	ADCSequenceStepConfigure(ADC_BASE, 0, 0, ADC_CTL_CH0 | ADC_CTL_IE | ADC_CTL_END);
	ADCSequenceEnable(ADC_BASE, 0);

	//
	// Send a welcome message to the UART.
	//
	OSRAM96x16x1Init(true);
	
	//
	// Enable to interrupt the processor
	//
	IntMasterEnable();

  	IntEnable(INT_GPIOC);    	
 	GPIOPinTypeGPIOInput(GPIO_PORTC_BASE, PUSH_BUTTON);
    GPIOIntTypeSet(GPIO_PORTC_BASE,PUSH_BUTTON,GPIO_RISING_EDGE);
	GPIOPinIntEnable(GPIO_PORTC_BASE, PUSH_BUTTON);
	
	//
    // Configure the three 32-bit periodic timers.
    //
    TimerConfigure(TIMER0_BASE, TIMER_CFG_32_BIT_OS);
    TimerConfigure(TIMER1_BASE, TIMER_CFG_32_BIT_OS);
	TimerConfigure(TIMER2_BASE, TIMER_CFG_32_BIT_PER);
	TimerLoadSet(TIMER0_BASE, TIMER_A, SysCtlClockGet()/2);
   	TimerLoadSet(TIMER1_BASE, TIMER_A, SysCtlClockGet()/6);
	TimerLoadSet(TIMER2_BASE, TIMER_A, SysCtlClockGet());
     
    //
    // Setup the interrupts for the timer timeouts.
    //
    IntEnable(INT_TIMER0A);
    TimerIntEnable(TIMER0_BASE, TIMER_TIMA_TIMEOUT);
    IntEnable(INT_TIMER1A);
    TimerIntEnable(TIMER1_BASE, TIMER_TIMA_TIMEOUT);
	IntEnable(INT_TIMER2A);
    TimerIntEnable(TIMER2_BASE, TIMER_TIMA_TIMEOUT);
	
	OSRAM96x16x1Clear();
	menuDraw();    
	result = GetDataFromACP();
	TimerEnable(TIMER2_BASE, TIMER_A);
	
	while(1)
	{	
		screenStart();
		result = GetDataFromACP();
		
		// Determines the position of the '#' sign using
		// the position of the potentiometer
		if (result < 25)
		{
			OSRAM96x16x1StringDraw("#", 0*6, 0);
			OSRAM96x16x1StringDraw(" ", 0*6, 1);
			OSRAM96x16x1StringDraw(" ", 6*9, 0);
		}
		else if (result < 75)
		{
			OSRAM96x16x1StringDraw(" ", 0*6, 0);
			OSRAM96x16x1StringDraw(" ", 0*6, 1);
			OSRAM96x16x1StringDraw("#", 6*9, 0);
		}
		else
		{
			OSRAM96x16x1StringDraw("#", 0*6, 1);
			OSRAM96x16x1StringDraw(" ", 6*9, 0);
			OSRAM96x16x1StringDraw(" ", 0*6, 0);
		}

		// starts the second menu when a click arrives
		if (state == 1)
		{
			state = 0;
			OSRAM96x16x1Clear();
			
			if (result < 25)
				inputCoefficients(coeffA);
			else if (result < 75)
				inputCoefficients(coeffB);
			else
				inputCoefficients(coeffC);
			state=0;
		}
	
		// Detects potentiometer and PUSH BUTTON activity
		if(resultTemp < (result-5) || resultTemp > (result+ 5) || state)
		{
			TimerEnable(TIMER2_BASE, TIMER_A);
			seconds=0;
			resultTemp=result;
		}
	}
}
